package com.olive.config;

import com.alibaba.fastjson2.JSON;
import com.olive.annotation.Encrypted;
import com.olive.dto.ResultInfo;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.nio.charset.StandardCharsets;

public class ResponseBodyHandler implements HandlerMethodReturnValueHandler {

    protected final HandlerMethodReturnValueHandler handlerMethodReturnValueHandler;

    public ResponseBodyHandler(HandlerMethodReturnValueHandler handlerMethodReturnValueHandler){
        this.handlerMethodReturnValueHandler = handlerMethodReturnValueHandler;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        //如果被@ResponseBody注解修饰的 返回true
        return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class))
                && returnType.hasMethodAnnotation(Encrypted.class);
    }

    @Override
    public void handleReturnValue(Object returnValue,
                                  MethodParameter returnType,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest) throws Exception {
        if(returnValue instanceof ResultInfo){
            ResultInfo<?> resultInfo = (ResultInfo<?>)returnValue;
            ResultInfo<String> newResultInfo = new ResultInfo<>();
            newResultInfo.setCode(resultInfo.getCode());
            newResultInfo.setMessage(resultInfo.getMessage());
            newResultInfo.setEncrypt(true);
            newResultInfo.setBody(Base64Utils.encodeToString(JSON.toJSONString(resultInfo.getBody()).getBytes(StandardCharsets.UTF_8)));
            //ResponseBody注解执行器
            handlerMethodReturnValueHandler.handleReturnValue(newResultInfo,
                    returnType, mavContainer, webRequest);
        }else{
            handlerMethodReturnValueHandler.handleReturnValue(returnValue,
                    returnType, mavContainer,  webRequest);
        }
    }
}
